package task.gui;
/*
 * Sash example snippet: implement a simple splitter (with a 20 pixel limit)
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 */
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.ControlEditor;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.TableCursor;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

import task.ConnectionDescription;
import task.Context;
import task.ITask;
import task.dao.ObjectDb;
import task.dao.TaskDao;
import task.dao.TaskDaoCPImpl;

public class TaskCrab {
	private static TaskDetailView taskDetailView;
	private static ArrayList<ConnectionDescription> conns;
	private static String currCD;
	private static String currTask;
//	private static TreeMap<String, String> globals;
	private static Context context;
	private static Table connTable;
	private static ObjectDb db = new ObjectDb("data/TaskCrab.xml"); 
	private static Clipboard clipboard;

	public static void main (String [] args) throws DocumentException, IOException {
		TaskDao taskDao = new TaskDaoCPImpl();
		String[] taskNames = taskDao.getTasks();
		ITask[] tasks = createTasks(taskNames);
		conns = (ArrayList<ConnectionDescription>) db.get("conns");
		if (conns == null) {
			conns = new ArrayList<ConnectionDescription>();
			db.put("conns", conns);
		}
		context = (Context) db.get("context");
		if (context == null) {
			context = new Context();
			db.put("context", context);
		}
		currCD = (String) db.get("currCD");
//		context.setGlobals(globals);
		
		Display display = new Display ();
		clipboard = new Clipboard(display);
		final Shell shell = new Shell (display);
		shell.setText("Task Crab");
		ImageData idata = new ImageData(TaskCrab.class.getResourceAsStream("/img/crab52x52.png"));
		Image image = new Image(display, idata);
		shell.setImage(image);
		createMenuBar(shell);
		
	//	Button button1 = new Button (shell, SWT.PUSH);
	//	button1.setText ("Button 1");
		ExpandBar bar = createExpandBar(shell, display, conns, tasks);
		
		final Sash sash = new Sash (shell, SWT.VERTICAL);
		SashForm sashForm = createSashForm(shell, conns);
	//	Button button2 = new Button (shell, SWT.PUSH);
	//	button2.setText ("Button 2");
		
		final FormLayout form = new FormLayout ();
		shell.setLayout (form);
		
		FormData formData = new FormData ();
		formData.left = new FormAttachment (0, 0);
		formData.right = new FormAttachment (sash, 0);
		formData.top = new FormAttachment (0, 0);
		formData.bottom = new FormAttachment (100, 0);
	//	button1.setLayoutData (button1Data);
		bar.setLayoutData (formData);
	
		final int limit = 20, percent = 50;
		final FormData sashData = new FormData ();
		sashData.left = new FormAttachment (percent, 0);
		sashData.top = new FormAttachment (0, 0);
		sashData.bottom = new FormAttachment (100, 0);
		sash.setLayoutData (sashData);
		sash.addListener (SWT.Selection, new Listener () {
			public void handleEvent (Event e) {
				Rectangle sashRect = sash.getBounds ();
				Rectangle shellRect = shell.getClientArea ();
				int right = shellRect.width - sashRect.width - limit;
				e.x = Math.max (Math.min (e.x, right), limit);
				if (e.x != sashRect.x)  {
					sashData.left = new FormAttachment (0, e.x);
					shell.layout ();
				}
			}
		});
		
		FormData form2Data = new FormData ();
		form2Data.left = new FormAttachment (sash, 0);
		form2Data.right = new FormAttachment (100, 0);
		form2Data.top = new FormAttachment (0, 0);
		form2Data.bottom = new FormAttachment (100, 0);
		sashForm.setLayoutData (form2Data);

		currTask = (String) db.get("currTask");
		if (currTask != null) {
			for (ITask task : tasks) {
				if (currTask.equals(task.getSignature())) {
					taskDetailView.setTask(task);
					break;
				}
			}
		}

		shell.setLocation(0, 0);
		shell.setSize(550, 500);
		shell.pack ();
		shell.open ();
		while (!shell.isDisposed ()) {
			if (!display.readAndDispatch ()) 
				display.sleep ();
		}
		display.dispose ();
		db.put("currCD", taskDetailView.getCurrCD());
		ITask task = taskDetailView.getTask();
		db.put("currTask", task!= null ? task.getSignature() : null);
		db.save();
	}
//	private static class MyShellListener implements ShellListener {
//		public boolean done = false;
//		public Point loc;
//		public Point size;
//
//
//		@Override
//		public void shellActivated(ShellEvent e) {
//			// TODO Auto-generated method stub
//			
//		}
//
//		@Override
//		public void shellClosed(ShellEvent e) {
//			System.out.printf("HERE%n");
//			Shell shell = (Shell) e.getSource();
//			loc = shell.getLocation();
//			size = shell.getSize();
//			done = true;
//		}
//
//		@Override
//		public void shellDeactivated(ShellEvent e) {
//			// TODO Auto-generated method stub
//			
//		}
//
//		@Override
//		public void shellDeiconified(ShellEvent e) {
//			// TODO Auto-generated method stub
//			
//		}
//
//		@Override
//		public void shellIconified(ShellEvent e) {
//			// TODO Auto-generated method stub
//			
//		}
//	}
	private static ITask[] createTasks(String[] taskNames) {
		ITask[] tasks = new ITask[taskNames.length];
		for (int i=0 ; i<tasks.length ; i++) {
			try {
				Class<?> cls = Class.forName(taskNames[i]);
				ITask task = (ITask) cls.newInstance();
				tasks[i] = task;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return tasks;
	}
	public static Document parse(File file) throws DocumentException {
	    SAXReader reader = new SAXReader();
	    Document document = reader.read(file);
	    return document;
	}
	public static ExpandBar createExpandBar(Composite parent, Display display, ArrayList<ConnectionDescription> conns, ITask[] tasks)
	{
		ExpandBar bar = new ExpandBar (parent, SWT.V_SCROLL);
		
//		Composite composite = new Composite (bar, SWT.NONE);
		Composite composite = createTasksComposite(bar, SWT.NONE, tasks);
//		GridLayout layout = new GridLayout (2, false);
//		layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 10;
//		layout.verticalSpacing = 10;
//		composite.setLayout(layout);
////		Image[] images = { display.getSystemImage(SWT.ICON_ERROR), display.getSystemImage(SWT.ICON_INFORMATION), 
////				display.getSystemImage(SWT.ICON_WARNING), display.getSystemImage(SWT.ICON_QUESTION)  
////		};
//		int i = 0;
//		for (String task : tasks) {
//			Label label = new Label (composite, SWT.NONE);
//			label.setImage(images[i++]);
//			i %= images.length;
//			label = new Label (composite, SWT.NONE);
//			label.setText(task);
//		}
		ExpandItem item1 = new ExpandItem (bar, SWT.NONE, 0);
		item1.setText("Tasks");
		ImageData idata = new ImageData(TaskCrab.class.getResourceAsStream("/img/samples16.png"));
		Image image = new Image(parent.getDisplay(), idata);
		item1.setImage(image);
		item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item1.setControl(composite);
		
		// Second item
		connTable = createConnectionTable(bar, display, conns);
		createMenu(parent.getShell(), connTable);
//		layout = new GridLayout ();
//		layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 10;
//		layout.verticalSpacing = 10;
//		composite.setLayout(layout);
		ExpandItem item2 = new ExpandItem (bar, SWT.NONE, 1);
		item2.setText("Database Connections");
		idata = new ImageData(TaskCrab.class.getResourceAsStream("/img/jdbc_16.gif"));
		image = new Image(parent.getDisplay(), idata);
		item2.setImage(image);
		item2.setHeight(connTable.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item2.setControl(connTable);
		
		item1.setExpanded(true);
		bar.setSpacing(8);

		Table propsTable = createPropsTable(bar, display);
		createMenu(parent.getShell(), propsTable);
//		layout = new GridLayout ();
//		layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 10;
//		layout.verticalSpacing = 10;
//		composite.setLayout(layout);
		ExpandItem item3 = new ExpandItem (bar, SWT.NONE, 2);
		item3.setText("Global Properties");
		idata = new ImageData(TaskCrab.class.getResourceAsStream("/img/migrate16.png"));
		image = new Image(parent.getDisplay(), idata);
		item3.setImage(image);
		item3.setHeight(propsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item3.setControl(propsTable);

		ExpandItem item4 = new ExpandItem (bar, SWT.NONE, 3);
		item4.setText("Tools");
		idata = new ImageData(TaskCrab.class.getResourceAsStream("/img/migrate16.png"));
		image = new Image(parent.getDisplay(), idata);
		item4.setImage(image);
		item4.setHeight(propsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
		item4.setControl(createToolsComposite(bar, SWT.NONE));

		item1.setExpanded(true);
		bar.setSpacing(8);

		return bar;
	}
	private static void createMenu(final Shell shell, final Table table) {
		Menu menu = new Menu (shell, SWT.POP_UP);
		MenuItem item = new MenuItem (menu, SWT.PUSH);
		item.setText ("Insert Row");
		item.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				int n = table.getColumnCount();
				String[] value = new String[n];
				for (int i=0 ; i<n ; i++) {
					value[i] = "";
				}
				int ndx = table.getSelectionIndex();
				TableItem item = new TableItem (table, SWT.NONE, ndx+1);
				item.setText(value);
				table.pack();
			}
		});
		item = new MenuItem (menu, SWT.PUSH);
		item.setText ("Delete Row");
		item.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			@Override
			public void widgetSelected(SelectionEvent e) {
				int ndx = table.getSelectionIndex();
				if (ndx>=0) {
					table.remove(ndx);
					TableColumn column = table.getColumn(1);
					if (column.getText().contains("URL")) {
						dump(table);
						taskDetailView.updateConnections(conns);
					} else {
						dumpProps(table);
					}
				}
			}
		});
		item = new MenuItem (menu, SWT.PUSH);
		item.setText ("Clone Row");
		item.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			@Override
			public void widgetSelected(SelectionEvent e) {
				int ndx = table.getSelectionIndex();
				if (ndx>=0) {
					System.out.printf("TODO:Clone row%n");
				}
			}
		});
		table.setMenu (menu);
	}
	private static Table createPropsTable(Composite parent, Display display) {
		String[] titles = {"Name", "Value"};
		final Table table = new Table (parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
		GridData data = new GridData (SWT.FILL, SWT.FILL, true, true);
		data.heightHint = 200;
		table.setLayoutData (data);
		table.setLinesVisible (true);
		table.setHeaderVisible (true);
		for (int i=0; i<titles.length; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setText (titles [i]);
		}	
		for (Map.Entry<String, String> e : context.getGlobals().entrySet()) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText(new String[] { e.getKey(), e.getValue()});
		}
		for (int i=0; i<titles.length; i++) {
			table.getColumn (i).pack ();
		}	
		// create a TableCursor to navigate around the table
		final TableCursor cursor = new TableCursor(table, SWT.NONE);
		// create an editor to edit the cell when the user hits "ENTER" 
		// while over a cell in the table
		final ControlEditor editor = new ControlEditor(cursor);
		editor.grabHorizontal = true;
		editor.grabVertical = true;
	
		cursor.addSelectionListener(new SelectionAdapter() {
			// when the TableEditor is over a cell, select the corresponding row in 
			// the table
			public void widgetSelected(SelectionEvent e) {
				table.setSelection(new TableItem[] {cursor.getRow()});
			}
			// when the user hits "ENTER" in the TableCursor, pop up a text editor so that 
			// they can change the text of the cell
			public void widgetDefaultSelected(SelectionEvent e){
				final Text text = new Text(cursor, SWT.NONE);
				TableItem row = cursor.getRow();
				int column = cursor.getColumn();
				text.setText(row.getText(column));
				text.addKeyListener(new KeyAdapter() {
					public void keyPressed(KeyEvent e) {
						// close the text editor and copy the data over 
						// when the user hits "ENTER"
						if (e.character == SWT.CR) {
							TableItem row = cursor.getRow();
							int column = cursor.getColumn();
							row.setText(column, text.getText());
							text.dispose();
							dumpProps(table);
						}
						// close the text editor when the user hits "ESC"
						if (e.character == SWT.ESC) {
							text.dispose();
						}
					}

				});
				editor.setEditor(text);
				text.setFocus();
			}
		});
		// Hide the TableCursor when the user hits the "MOD1" or "MOD2" key.
		// This allows the user to select multiple items in the table.
		cursor.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.MOD1 || 
				    e.keyCode == SWT.MOD2 || 
				    (e.stateMask & SWT.MOD1) != 0 || 
				    (e.stateMask & SWT.MOD2) != 0) {
					cursor.setVisible(false);
				}
			}
		});
		// Show the TableCursor when the user releases the "MOD2" or "MOD1" key.
		// This signals the end of the multiple selection task.
		table.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent e) {
				if (e.keyCode == SWT.MOD1 && (e.stateMask & SWT.MOD2) != 0) return;
				if (e.keyCode == SWT.MOD2 && (e.stateMask & SWT.MOD1) != 0) return;
				if (e.keyCode != SWT.MOD1 && (e.stateMask & SWT.MOD1) != 0) return;
				if (e.keyCode != SWT.MOD2 && (e.stateMask & SWT.MOD2) != 0) return;
			
				TableItem[] selection = table.getSelection();
				TableItem row = (selection.length == 0) ? table.getItemCount() == 0 ? null : table.getItem(table.getTopIndex()) : selection[0];
				if (row != null) {
					table.showItem(row);
					cursor.setSelection(row, 0);
				}
				cursor.setVisible(true);
				cursor.setFocus();
			}
		});
		return table;
	}
	public static Table createConnectionTable(Composite parent, Display display, final ArrayList<ConnectionDescription> conns) 
	{
		String[] titles = {"Name", "URL", "User", "Password"};
		final Table table = new Table (parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
		GridData data = new GridData (SWT.FILL, SWT.FILL, true, true);
		data.heightHint = 200;
		table.setLayoutData (data);
		table.setLinesVisible (true);
		table.setHeaderVisible (true);
		for (int i=0; i<titles.length; i++) {
			TableColumn column = new TableColumn (table, SWT.NONE);
			column.setText (titles [i]);
		}	
		for (ConnectionDescription conn : conns) {
			TableItem item = new TableItem (table, SWT.NONE);
			item.setText(new String[] { conn.getName(), conn.getUrl(), conn.getUser(), conn.getPasswd()});
		}
		for (int i=0; i<titles.length; i++) {
			table.getColumn (i).pack ();
		}	
		// create a TableCursor to navigate around the table
		final TableCursor cursor = new TableCursor(table, SWT.NONE);
		// create an editor to edit the cell when the user hits "ENTER" 
		// while over a cell in the table
		final ControlEditor editor = new ControlEditor(cursor);
		editor.grabHorizontal = true;
		editor.grabVertical = true;
	
		cursor.addSelectionListener(new SelectionAdapter() {
			// when the TableEditor is over a cell, select the corresponding row in 
			// the table
			public void widgetSelected(SelectionEvent e) {
				table.setSelection(new TableItem[] {cursor.getRow()});
			}
			// when the user hits "ENTER" in the TableCursor, pop up a text editor so that 
			// they can change the text of the cell
			public void widgetDefaultSelected(SelectionEvent e){
				final Text text = new Text(cursor, SWT.NONE);
				TableItem row = cursor.getRow();
				int column = cursor.getColumn();
				text.setText(row.getText(column));
				text.addKeyListener(new KeyAdapter() {
					public void keyPressed(KeyEvent e) {
						// close the text editor and copy the data over 
						// when the user hits "ENTER"
						if (e.character == SWT.CR) {
							TableItem row = cursor.getRow();
							int column = cursor.getColumn();
							row.setText(column, text.getText());
							text.dispose();
							dump(table);
							if (column == 0) {
								taskDetailView.updateConnections(conns);
							}
						}
						// close the text editor when the user hits "ESC"
						if (e.character == SWT.ESC) {
							text.dispose();
						}
					}

				});
				editor.setEditor(text);
				text.setFocus();
			}
		});
		// Hide the TableCursor when the user hits the "MOD1" or "MOD2" key.
		// This allows the user to select multiple items in the table.
		cursor.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.MOD1 || 
				    e.keyCode == SWT.MOD2 || 
				    (e.stateMask & SWT.MOD1) != 0 || 
				    (e.stateMask & SWT.MOD2) != 0) {
					cursor.setVisible(false);
				}
			}
		});
		// Show the TableCursor when the user releases the "MOD2" or "MOD1" key.
		// This signals the end of the multiple selection task.
		table.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent e) {
				if (e.keyCode == SWT.MOD1 && (e.stateMask & SWT.MOD2) != 0) return;
				if (e.keyCode == SWT.MOD2 && (e.stateMask & SWT.MOD1) != 0) return;
				if (e.keyCode != SWT.MOD1 && (e.stateMask & SWT.MOD1) != 0) return;
				if (e.keyCode != SWT.MOD2 && (e.stateMask & SWT.MOD2) != 0) return;
			
				TableItem[] selection = table.getSelection();
				TableItem row = (selection.length == 0) ? table.getItem(table.getTopIndex()) : selection[0];
				table.showItem(row);
				cursor.setSelection(row, 0);
				cursor.setVisible(true);
				cursor.setFocus();
			}
		});
		return table;
	}
	private static void dump(Table table) {
		int diff = table.getItemCount() - conns.size();
		while (diff>0) {
			conns.add(new ConnectionDescription());
			diff--;
		}
		while (diff<0) {
			conns.remove(0);
			diff++;
		}
		for (int i=0,n=table.getItemCount() ; i<n ; i++) {
			TableItem item = table.getItem(i);
			conns.get(i).setName(item.getText(0));
			conns.get(i).setUrl(item.getText(1));
			conns.get(i).setUser(item.getText(2));
			conns.get(i).setPasswd(item.getText(3));
		}
	}
	private static void dumpProps(Table table) {
		context.getGlobals().clear();
		for (int i=0,n=table.getItemCount() ; i<n ; i++) {
			TableItem item = table.getItem(i);
			context.getGlobals().put(item.getText(0), item.getText(1));
		}
	}
	public static SashForm createSashForm(Composite parent, ArrayList<ConnectionDescription> conns) {
		SashForm form = new SashForm(parent, SWT.VERTICAL);
		form.setLayout(new FillLayout());
		
		Composite child1 = new Composite(form,SWT.NONE);
		child1.setLayout(new FillLayout());
		final Group group1 = new Group(child1, SWT.SHADOW_ETCHED_IN);
		group1.setLayout(new FillLayout());
		group1.setText("Task");
		taskDetailView = new TaskDetailView(group1, SWT.EMBEDDED, conns, context);
		taskDetailView.setCurrCD(currCD);
//		final Text text0 = new Text (group1, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
	
		
		
		Composite child3 = new Composite(form,SWT.NONE);
		child3.setLayout(new FillLayout());
		final Group group2 = new Group(child3, SWT.SHADOW_ETCHED_IN);
		group2.setLayout(new FillLayout());
		group2.setText("Output");
		final Text outText = new Text (group2, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		outText.setEditable(false);

		outText.setFont(new Font(Display.getDefault(), "Courier New", 8, SWT.NORMAL));

		System.setOut(new PrintStream(new TextOutputStream(outText)));
//		System.setErr(new PrintStream(new TextOutputStream(text1)));
		form.setWeights(new int[] {30,50});
		Menu menu = new Menu (parent.getShell(), SWT.POP_UP);
		MenuItem item = new MenuItem (menu, SWT.PUSH);
		item.setText ("Clear");
		item.addSelectionListener(new SelectionListener(){
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			@Override
			public void widgetSelected(SelectionEvent e) {
				outText.setText("");
			}});
		outText.setMenu (menu);

		return form;
	}
	static ScrolledComposite createTasksComposite(Composite parent, int style, ITask[] tasks) {
		final ScrolledComposite sc =  new ScrolledComposite(parent, style);
		sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		Composite c = new Composite(sc, SWT.NONE);
		c.setLayout(new GridLayout(2, true));
		for (ITask task : tasks) {
			new TaskButtonAdmin(c, SWT.PUSH, task);
		}
		sc.setContent(c);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);
		sc.setMinSize(c.computeSize(SWT.DEFAULT, SWT.DEFAULT));
		sc.setShowFocusedControl(true);
		return sc;
	}
	static ScrolledComposite createToolsComposite(final Composite parent, int style) {
		final ScrolledComposite sc =  new ScrolledComposite(parent, style);
		sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		Composite c = new Composite(sc, SWT.NONE);
		c.setLayout(new GridLayout(2, true));

		Button b = new Button(c, style);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
		b.setText("FileName");
		b.setLayoutData(gridData);	
		b.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				System.out.printf("filename%n");
				FileDialog dialog = new FileDialog(parent.getShell(), SWT.OPEN);
				String filename = dialog.open();
				if (filename == null) {
					System.out.printf("Nothing changed in clipboard%n");
				} else {
					TextTransfer textTransfer = TextTransfer.getInstance();
					clipboard.setContents(new Object[]{filename}, new Transfer[]{textTransfer});
					System.out.printf("Filename put in clipboard: '%s'%n", filename);
				}
			}
		});
		sc.setContent(c);
		sc.setExpandHorizontal(true);
		sc.setExpandVertical(true);
		sc.setMinSize(c.computeSize(SWT.DEFAULT, SWT.DEFAULT));
		sc.setShowFocusedControl(true);
		return sc;
	}
	static class TaskButtonAdmin {
		private final ITask task;

		public TaskButtonAdmin(Composite parent, int style, ITask task) {
			Button b = new Button(parent, style);
			this.task= task;
			GridData gridData = new GridData();
			gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
			b.setText(task.getName());
			ImageData data = task.getImageData();
			if (data != null) {
				Image image = new Image(parent.getDisplay(), data);
				b.setImage(image);
			}
			b.setLayoutData(gridData);	
			b.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
				public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
					System.out.println("Select : " + TaskButtonAdmin.this.task.getName());
					taskDetailView.setTask(TaskButtonAdmin.this.task);
				}
			});
		}
	}
	private static void createMenuBar(Shell shell) {
		Menu bar = new Menu(shell, SWT.BAR);
		shell.setMenuBar(bar);
		MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
		fileItem.setText("&File");
		Menu submenu = new Menu(shell, SWT.DROP_DOWN);
		fileItem.setMenu(submenu);
		MenuItem item = new MenuItem(submenu, SWT.PUSH);
		item.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				db.backup("data/TaskCrab-backup.xml");
			}
		});
		item.setText("&Backup Connections\tCtrl+B");
		item.setAccelerator(SWT.MOD1 + 'B');

		item = new MenuItem(submenu, SWT.PUSH);
		item.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
//				restoreConnections();
			}
		});
		item.setText("&Restore Connections\tCtrl+R");
		item.setAccelerator(SWT.MOD1 + 'R');
	}
//	private static void restoreConnections() {
//		File file = new File("data/connections.backup.json");
//		try {
//			List<Map<String, String>> list = ObjectDb.mapper.readValue(file, List.class);
//			conns.clear();
//			for (Map<String, String> map : list) {
//				ConnectionDescription cd = new ConnectionDescription();
//				conns.add(cd);
//				cd.setName(map.get("name"));
//				cd.setUrl(map.get("url"));
//				cd.setUser(map.get("user"));
//				cd.setPasswd(map.get("passwd"));
//			}
//			for (ConnectionDescription conn : conns) {
//				connTable.clearAll();
//				TableItem item = new TableItem (connTable, SWT.NONE);
//				item.setText(new String[] { conn.getName(), conn.getUrl(), conn.getUser(), conn.getPasswd()});
//			}
//		} catch (Exception e) {
//			throw new RuntimeException(e);
//		}
//	}
} 
